package com.liuceng.zen.web.controller;

import com.alibaba.fastjson.JSONArray;
import com.liuceng.zen.Page;
import com.liuceng.zen.mapper.NewRptFrontCampaignDailyMapper;
import com.liuceng.zen.pojo.domain.BaseDomain;
import com.liuceng.zen.pojo.domain.MikeFormData;
import com.liuceng.zen.pojo.form.MikeFormDataForm;
import com.liuceng.zen.pojo.form.ReportForm;
import com.liuceng.zen.service.MikeFormDataService;
import com.liuceng.zen.service.RptFrontAdGroupDailyService;
import com.liuceng.zen.service.RptFrontCampaignDailyService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * ReortController.java 报表的相关功能
 *
 * @author wangyanwen
 *
 */
@Controller
public class ReportController extends BaseController {
  @Autowired
  private RptFrontCampaignDailyService rptFrontCampaignDailyService;
  @Autowired
  private RptFrontAdGroupDailyService rptFrontAdGroupDailyService;
  @Autowired
  NewRptFrontCampaignDailyMapper NewRptFrontCampaignDailyMapper;
  @Autowired
  private MikeFormDataService mikeFormDataService;

  // 统计报表---整体统计
  @RequestMapping(value = "/reports", method = RequestMethod.GET)
  public String memberRpt(@ModelAttribute("form") ReportForm form) {
    Map<String, Object> params = new HashMap<>();
    params.put("memberId", getCurrentUserId());
    params.put("orderBy", "desc");
    params.put("auditType", BaseDomain.AUDIT_PASS);
    // 按天分隔，获取每天的总花费，总曝光量，总点击量
    List<Map<String, Object>> memberRpts = NewRptFrontCampaignDailyMapper.findMemberRptData(params);
    memberRpts.stream().map(rpt -> {
      // 批量处理
      // 点击率
      rpt.put("ctr",
          rpt.get("pv") == null || 0 == Integer.parseInt(rpt.get("pv").toString())
              ? new BigDecimal(0)
              : new BigDecimal(Integer.parseInt(rpt.get("pc").toString()) * 100)
                  .divide(new BigDecimal(rpt.get("pv").toString()), 3, RoundingMode.UP));
      // 点击均价
      rpt.put("avgClickCost",
          rpt.get("pc") == null || 0 == Integer.parseInt(rpt.get("pc").toString())
              ? new BigDecimal(0)
              : new BigDecimal(rpt.get("total_cost").toString())
                  .divide(new BigDecimal(rpt.get("pc").toString()), 3, RoundingMode.UP));
      // 千次曝光费用
      rpt.put("viewCost",
          rpt.get("pv") == null || 0 == Integer.parseInt(rpt.get("pv").toString())
              ? new BigDecimal(0)
              : new BigDecimal(rpt.get("total_cost").toString()).multiply(new BigDecimal(1000))
                  .divide(new BigDecimal(rpt.get("pv").toString()), 3, RoundingMode.UP));
      //
      return rpt;
    }).collect(Collectors.toList());

    form.setRpts(memberRpts);
    //
    return "report/member";
  }

  // 统计报表---整体统计---渲染图表
  @RequestMapping(value = "/ajax/reports/data", method = RequestMethod.GET)
  public @ResponseBody List<Map<String, Object>> memberRptData() {
    Map<String, Object> params = new HashMap<>();
    params.put("memberId", getCurrentUserId());
    params.put("auditType", BaseDomain.AUDIT_PASS);
    params.put("orderBy", "asc");
    // 按天分隔，获取每天的总花费，总曝光量，总点击量
    List<Map<String, Object>> memberRpts = NewRptFrontCampaignDailyMapper.findMemberRptData(params);
    memberRpts.stream().map(d -> {
      d.put("total_cost",d.get("total_cost")==null?new BigDecimal(0) :((BigDecimal)d.get("total_cost")).divide(new BigDecimal(1), 2, RoundingMode.HALF_DOWN));
      return JSONArray.toJSON(d);
    }).collect(Collectors.toList());
    //
    return memberRpts;
  }

  // 统计报表---计划统计
  @RequestMapping(value = "/reports/campaigns", method = RequestMethod.GET)
  public String campaignRpt(@ModelAttribute("form") ReportForm form) {
    Map<String, Object> params = new HashMap<>();
    params.put("memberId", getCurrentUserId());
    params.put("orderBy", "desc");
    params.put("auditType", BaseDomain.AUDIT_PASS);
    // 按天分隔，获取每天的总花费，总曝光量，总点击量，最大广告计划名，广告计划类型
    List<Map<String, Object>> campaigns =
        NewRptFrontCampaignDailyMapper.findCampaignRptData(params);
    campaigns.stream().map(rpt -> {
      // 批量处理
      // 点击率
      rpt.put("ctr",
          rpt.get("pv") == null || 0 == Integer.parseInt(rpt.get("pv").toString())
              ? new BigDecimal(0)
              : new BigDecimal(Integer.parseInt(rpt.get("pc").toString()) * 100)
                  .divide(new BigDecimal(rpt.get("pv").toString()), 3, RoundingMode.UP));
      // 点击均价
      rpt.put("avgClickCost",
          rpt.get("pc") == null || 0 == Integer.parseInt(rpt.get("pc").toString())
              ? new BigDecimal(0)
              : new BigDecimal(rpt.get("total_cost").toString())
                  .divide(new BigDecimal(rpt.get("pc").toString()), 3, RoundingMode.UP));
      // 千次曝光费用
      rpt.put("viewCost",
          rpt.get("pv") == null || 0 == Integer.parseInt(rpt.get("pv").toString())
              ? new BigDecimal(0)
              : new BigDecimal(rpt.get("total_cost").toString()).multiply(new BigDecimal(1000))
                  .divide(new BigDecimal(rpt.get("pv").toString()), 3, RoundingMode.UP));
      //
      return rpt;
    }).collect(Collectors.toList());
    form.setCampaignRpts(campaigns);
    //
    return "report/campaigns";
  }


  // 统计报表---广告统计
  @RequestMapping(value = "/reports/ads", method = RequestMethod.GET)
  public String adRpt(@ModelAttribute("form") ReportForm form) {
    Map<String, Object> params = new HashMap<>();
    params.put("memberId", getCurrentUserId());
    params.put("orderBy", "desc");
    // 获取
    List<Map<String, Object>> ads = rptFrontCampaignDailyService.findAdGroupRptData(params);
    ads.stream().map(rpt -> {
      // 批量处理
      // 点击率
      rpt.put("ctr",
          rpt.get("pv") == null || 0 == Integer.parseInt(rpt.get("pv").toString())
              ? new BigDecimal(0)
              : new BigDecimal(Integer.parseInt(rpt.get("pc").toString()) * 100)
                  .divide(new BigDecimal(rpt.get("pv").toString()), 3, RoundingMode.UP));
      // 点击均价
      rpt.put("avgClickCost",
          rpt.get("pc") == null || 0 == Integer.parseInt(rpt.get("pc").toString())
              ? new BigDecimal(0)
              : new BigDecimal(rpt.get("cost").toString())
                  .divide(new BigDecimal(rpt.get("pc").toString()), 3, RoundingMode.UP));
      // 千次曝光费用
      rpt.put("viewCost",
          rpt.get("pv") == null || 0 == Integer.parseInt(rpt.get("pv").toString())
              ? new BigDecimal(0)
              : new BigDecimal(rpt.get("cost").toString())
                  .divide(new BigDecimal(rpt.get("pv").toString() + "000"), 3, RoundingMode.UP));
      //
      return rpt;
    }).collect(Collectors.toList());
    form.setAdgroupRpts(ads);
    //
    return "report/ads";
  }

  @RequestMapping(value = "/reports/forms", method = RequestMethod.GET)
  public String formStatistics() {

    return "report/formStatistics";
  }

  // 表单统计
  @RequestMapping(value = "/reports/forms", method = RequestMethod.POST)
  public @ResponseBody Object formStatistics(MikeFormDataForm mikeFormDataForm,
      HttpServletRequest req) {
    // 初始化信息
    mikeFormDataForm.setSortInfo(req);
    mikeFormDataForm.setMemberId(getCurrentUserId());
    Page<MikeFormData> MikeFormDatas = mikeFormDataService.findPage(mikeFormDataForm);
    List<MikeFormData> list = MikeFormDatas.getContent();
    Map<String, Object> filterMap = new HashMap<String, Object>();
    filterMap.put("sEcho", 0);
    filterMap.put("iTotalRecords", MikeFormDatas.getContent().size());// 实际的行数
    filterMap.put("iTotalDisplayRecords", MikeFormDatas.getTotalCount());// 总行数
    filterMap.put("data", MikeFormDatas.getContent());// 要以JSON格式返回
    return filterMap;
  }

  @RequestMapping(value = "/reports/forms/{id}", method = RequestMethod.POST)
  public @ResponseBody Object form(@PathVariable Integer id, MikeFormDataForm mikeFormDataForm,
      HttpServletRequest req) {
    // 初始化信息
    MikeFormData mikeFormData = mikeFormDataService.find(id);
    mikeFormData.setStatus(mikeFormDataForm.getStatus());
    mikeFormData.setRemark(mikeFormDataForm.getRemark());
    mikeFormDataService.update(mikeFormData);
    return "success";
  }

  @RequestMapping(value = "/reports/forms/{id}", method = RequestMethod.GET)
  public @ResponseBody Object checkForm(@PathVariable Integer id) {
    // 初始化信息
    MikeFormData mikeFormData = mikeFormDataService.find(id);
    Map<String, Object> map = new HashMap<>();
    map.put("status", mikeFormData.getStatus());
    map.put("remark", mikeFormData.getRemark());
    return map;
  }

    @RequestMapping(value = "/reports/mikeDetail/{id}", method = RequestMethod.GET)
    public @ResponseBody Object mikeDetail(@PathVariable Integer id) {
        //根据mike表单的id查询表单的详细信息
        MikeFormData mikeFormData = mikeFormDataService.find(id);
        return mikeFormData;
    }

  // 表单统计详情
  // @RequestMapping(value = "/reports/forms/{formId}", method = RequestMethod.GET)
  // public String formStatisticsdetail(@PathVariable Integer formId,
  // @ModelAttribute("form") MikeFormDataForm form) {
  // MikeFormData mikeFormData = mikeFormDataService.selectByPrimaryKey(formId);
  // form.setMikeFormData(mikeFormData);
  // return "report/formStatisticsdetail";
  // }

  // 表单统计
  @RequestMapping(value = "/reports/exportCsv", method = RequestMethod.POST)
  public void exportCsv(String createdAt, String end_date, String range,
    HttpServletRequest req,HttpServletResponse response,String value1,String value2) throws ParseException {
    // 初始化信息
      Map<String, Object> filteMap = new HashMap();
      SimpleDateFormat simple = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
      MikeFormDataForm mikeFormDataForm = new MikeFormDataForm();
      mikeFormDataForm.setsSearch_1(createdAt);
      mikeFormDataForm.setsSearch_2(end_date);
      mikeFormDataForm.setsSearch_3(range);
      mikeFormDataForm.setsSearch_5(value1);//新增姓名
      mikeFormDataForm.setsSearch_0(value2);//新增手机号
      mikeFormDataForm.setMemberId(getCurrentUserId());
      String startTime="";
      String endTime = "";
      if (mikeFormDataForm.getsSearch_1() != null && !mikeFormDataForm.getsSearch_1().trim().equals("")) {
          filteMap.put("startTime", simple.parse(mikeFormDataForm.getsSearch_1().trim() + " 00:00:00"));
      }
      if (mikeFormDataForm.getsSearch_2() != null && !mikeFormDataForm.getsSearch_2().trim().equals("")) {
          filteMap.put("endTime", simple.parse(mikeFormDataForm.getsSearch_2().trim() + " 23:59:59"));
      }
      //新增姓名，手机号导出
      if (mikeFormDataForm.getsSearch_5() != null && !mikeFormDataForm.getsSearch_5().trim().equals("")) {
          filteMap.put("value1",mikeFormDataForm.getsSearch_5().trim());
      }
      if (mikeFormDataForm.getsSearch_0() != null && !mikeFormDataForm.getsSearch_0().trim().equals("")) {
          filteMap.put("value2",mikeFormDataForm.getsSearch_0().trim());
      }
      //快捷查询状态
      if (mikeFormDataForm.getsSearch_3() != null && !mikeFormDataForm.getsSearch_3().trim().equals("")) {
          SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
          Calendar now = Calendar.getInstance();
          now.setTime(new Date());
          if (mikeFormDataForm.getsSearch_3().trim().equals("seven")) {//最近七天
              now.set(Calendar.DATE, now.get(Calendar.DATE) - 7);
              filteMap.put("startTime", simple.parse((format.format(now.getTime()) + " 00:00:00")));
              filteMap.put("endTime", simple.parse((format.format(new Date()) + " 23:59:59")));
          }
          if (mikeFormDataForm.getsSearch_3().trim().equals("thirty")) {//最近三十天
              now.set(Calendar.DATE, now.get(Calendar.DATE) - 30);
              filteMap.put("startTime", simple.parse((format.format(now.getTime()) + " 00:00:00")));
              filteMap.put("endTime", simple.parse((format.format(new Date()) + " 23:59:59")));
          }
      }
      filteMap.put("memberId", mikeFormDataForm.getMemberId());
      List<MikeFormData> list = mikeFormDataService.selectByexport(filteMap);//获取数据
      //导出csv
      String displayColNames = null;
      String matchColNames = null;
      String fileName = null;
      String content = null;

      // 完成数据csv文件的封装
      displayColNames = "接收时间,姓名,手机号码,备注,状态";
      matchColNames = "createdAt,value1,value2,remark,status";
      fileName = "表单统计";
      content = formatCsvData(list, displayColNames, matchColNames);
      try {
          exportCsv(fileName, content, response);
      } catch (IOException e) {
          e.printStackTrace();
      }

  }

    /**
     *
     * 将检索数据输出的对应的csv列中
     * */
    public static String formatCsvData(List<MikeFormData> data,String displayColNames, String matchColNames) {
        StringBuffer buf = new StringBuffer();
        SimpleDateFormat simple = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        /** CSV文件列分隔符 */
        final String CSV_COLUMN_SEPARATOR = ",";

        /** CSV文件列分隔符 */
        final String CSV_RN = "\r\n";
        String[] displayColNamesArr = null;
        String[] matchColNamesMapArr = null;

        displayColNamesArr = displayColNames.split(",");
        matchColNamesMapArr = matchColNames.split(",");

        // 输出列头
        for (int i = 0; i < displayColNamesArr.length; i++) {
            buf.append(displayColNamesArr[i]).append(CSV_COLUMN_SEPARATOR);
        }
        buf.append(CSV_RN);

        if (null != data) {
            // 输出数据
            for (int i = 0; i < data.size(); i++) {
                    if (null != data.get(i).getCreatedAt()) {
                        buf.append(simple.format(data.get(i).getCreatedAt())).append(CSV_COLUMN_SEPARATOR);
                    } else {
                        buf.append("").append(CSV_COLUMN_SEPARATOR);
                    }
                    buf.append(data.get(i).getValue1()==null?"":data.get(i).getValue1()).append(CSV_COLUMN_SEPARATOR);
                    buf.append(data.get(i).getValue2()==null?"":data.get(i).getValue2()).append(CSV_COLUMN_SEPARATOR);
                    buf.append(data.get(i).getRemark()==null?"":data.get(i).getRemark()).append(CSV_COLUMN_SEPARATOR);
                    if (null != data.get(i).getStatus() && data.get(i).getStatus() == 0) {
                        buf.append("待处理").append(CSV_COLUMN_SEPARATOR);
                    } else if (null != data.get(i).getStatus() && data.get(i).getStatus() == 1){
                        buf.append("有效").append(CSV_COLUMN_SEPARATOR);
                    } else if (null != data.get(i).getStatus() && data.get(i).getStatus() == 2){
                        buf.append("待定").append(CSV_COLUMN_SEPARATOR);
                    } else if (null != data.get(i).getStatus() && data.get(i).getStatus() == 3){
                        buf.append("无效").append(CSV_COLUMN_SEPARATOR);
                    } else {
                        buf.append("").append(CSV_COLUMN_SEPARATOR);
                    }
                    buf.append(CSV_RN);
            }
        }
        return buf.toString();
    }

    public static void exportCsv(String fileName, String content,  HttpServletResponse response) throws IOException {
        // 设置文件后缀
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddhh24mmss");
        //String fn = fileName.concat(fileName + sdf.format(new Date()).toString() + ".csv");
        String fn = sdf.format(new Date()).toString() + ".csv";
        // 读取字符编码
        //String csvEncoding = PropertiesUtil.getProperty("CSV_ENCODING");

        // 设置响应
        response.setCharacterEncoding("gbk");
        response.setContentType("text/csv; charset=" + "gbk");
        response.setHeader("Pragma", "public");
        response.setHeader("Cache-Control", "max-age=30");
        response.setHeader("Content-Disposition", "attachment; filename="+ new String(fn.getBytes(), "gbk"));
        // 写出响应
        OutputStream os = response.getOutputStream();
        os.write(content.getBytes("GBK"));
        os.flush();
        os.close();
    }

}
